package com.gb.demand.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gb.demand.common.api.ResultMap;
import com.gb.demand.common.entity.Accessory;
import com.gb.demand.common.entity.Apilog;
import com.gb.demand.common.entity.Area;
import com.gb.demand.common.entity.Store;
import com.gb.demand.common.mapper.AccessoryMapper;
import com.gb.demand.common.mapper.AreaMapper;
import com.gb.demand.service.IAccessoryService;
import com.gb.demand.service.IApilogService;
import com.gb.demand.service.IAreaService;
import com.gb.demand.service.IStoreService;
import com.gb.demand.service.ex.ServiceException;
import com.gb.demand.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 用户业务层模块<p>
 *
 * @author wengjiangle
 * @since 2020/7/13
 */
@Slf4j
@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements IAreaService {

    @Autowired
    private IStoreService storeService;

    @Autowired
    private IApilogService apilogService;

    @Resource
    private AreaMapper areaMapper;

    /**
     * 查询省信息接口
     *
     * @param data
     * @return
     */
    @Override
    public Map getProvinceInfo(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String accessToken = String.valueOf(appinfoMap.get("accessToken"));
        String appKey = String.valueOf(appinfoMap.get("appKey"));
        // 判断token是否过期
        boolean isExpired = true;
        try {
            isExpired = storeService.checkAccessToken(appKey, accessToken);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false)),
                    "新点-查询省信息接口");
            return ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false);
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false)),
                    "新点-查询省信息接口");
            return ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false);
        }
        if (isExpired) {
            try {
                //  省的level=0 获取所有省 对象
                List<Area> areaList = areaMapper.selectAreaByLevel(0);
                // 转换成返回字段 province 的值所需要的格式
                List<Map> result = this.generateProvinceInfoForProvince(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("province", result, "获取省信息成功", true)),
                        "新点-查询省信息接口");
                return ResultMap.generateResultMapwithKey("province", result, "获取省信息成功", true);
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false)),
                        "新点-查询省信息接口");
                return ResultMap.generateResultMapwithKey("province", "", e.getMessage(), false);
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("province", "", "Token过期失效", false)),
                    "新点-查询省信息接口");
            return ResultMap.generateResultMapwithKey("province", "", "Token过期失效", false);
        }
    }

    /**
     * 查询市信息接口
     *
     * @param data
     * @return
     */
    @Override
    public Map getCityInfo(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String accessToken = String.valueOf(appinfoMap.get("accessToken"));
        String appKey = String.valueOf(appinfoMap.get("appKey"));
        String provinceId = String.valueOf(appinfoMap.get("provinceId"));//需要查询的市 所属的省
        // 判断token是否过期
        boolean isExpired = true;
        try {
            isExpired = storeService.checkAccessToken(appKey, accessToken);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false)),
                    "新点-查询市信息接口");
            return ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false);
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false)),
                    "新点-查询市信息接口");
            return ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false);
        }
        if (isExpired) {
            try {
                // 市的level=1
                List<Area> areaList = areaMapper.selectAreaCityByProvinceIdAndlevel(1, provinceId);
                // 生成返回字段 city 所需格式
                List<Map> result = this.generateProvinceInfoForProvince(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", result, "获取市信息成功", true)),
                        "新点-查询市信息接口");
                return ResultMap.generateResultMapwithKey("city", result, "获取市信息成功", true);
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false)),
                        "新点-查询市信息接口");
                return ResultMap.generateResultMapwithKey("city", "", e.getMessage(), false);
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", "", "Token过期失效", false)),
                    "新点-查询市信息接口");
            return ResultMap.generateResultMapwithKey("city", "", "Token过期失效", false);
        }
    }

    /**
     * 查询区信息接口
     *
     * @param data
     * @return
     */
    @Override
    public Map getDistrictInfo(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String accessToken = String.valueOf(appinfoMap.get("accessToken"));
        String appKey = String.valueOf(appinfoMap.get("appKey"));
        String cityId = String.valueOf(appinfoMap.get("cityId"));//需要查询的区 所属的市
        // 判断token是否过期
        boolean isExpired = true;
        try {
            isExpired = storeService.checkAccessToken(appKey, accessToken);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false)),
                    "新点-查询区信息接口");
            return ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false);
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false)),
                    "新点-查询区信息接口");
            return ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false);
        }

        // 如果没有过期
        if (isExpired) {
            try {
                // 区的level=2
                List<Area> areaList = areaMapper.selectAreaCityByProvinceIdAndlevel(2, cityId);
                // 生成返回字段 city 所需格式
                List<Map> result = this.generateProvinceInfoForProvince(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("district", result, "获取区信息成功", true)),
                        "新点-查询区信息接口");
                return ResultMap.generateResultMapwithKey("district", result, "获取区信息成功", true);
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false)),
                        "新点-查询区信息接口");
                return ResultMap.generateResultMapwithKey("district", "", e.getMessage(), false);
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.generateResultMapwithKey("district", "", "Token过期失效", false)),
                    "新点-查询区信息接口");
            return ResultMap.generateResultMapwithKey("district", "", "Token过期失效", false);
        }
    }

    /**
     * 公采云获取一级地址
     *
     * @param data
     * @return
     */
    @Override
    public Map getProvinces(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String token = String.valueOf(appinfoMap.get("token"));
        //根据token获取appkey
        Store store = new Store().selectOne(new LambdaQueryWrapper<Store>().eq(Store::getAccessToken, token));
        // 判断token是否过期
        boolean isExpired = true;
        String appKey = store.getAppKey();
        try {
            isExpired = storeService.checkAccessToken(appKey, token);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询省信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询省信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        }
        if (isExpired) {
            try {
                //  省的level=0 获取所有省 对象
                List<Area> areaList = areaMapper.selectAreaByLevel(0);
                // 转换成返回字段 province 的值所需要的格式
                List<Map> result = this.generateProvinceInfoForProvinceGcy(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.gcySuccessResultMapwithKey("result", result)),
                        "公采云-查询省信息接口");
                return ResultMap.gcySuccessResultMapwithKeyandDesc("result", result, "获取一级地址成功");
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                        "公采云-查询省信息接口");
                return ResultMap.gcyFaileResultMap(e.getMessage());
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileTokenResultMap()),
                    "公采云-查询省信息接口");
            return ResultMap.gcyFaileTokenResultMap();
        }
    }

    /**
     * 公采云获取二级地址
     *
     * @param data
     * @return
     */
    @Override
    public Map getCities(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String token = String.valueOf(appinfoMap.get("token"));
        String id = String.valueOf(appinfoMap.get("id"));//需要查询的市 所属的省
        //根据token获取appkey
        Store store = new Store().selectOne(new LambdaQueryWrapper<Store>().eq(Store::getAccessToken, token));
        // 判断token是否过期
        boolean isExpired = true;
        String appKey = store.getAppKey();
        try {
            isExpired = storeService.checkAccessToken(appKey, token);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询市信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询市信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        }
        if (isExpired) {
            try {
                // 市的level=1
                List<Area> areaList = areaMapper.selectAreaCityByProvinceIdAndlevel(1, id);
                // 生成返回字段 city 所需格式
                List<Map> result = this.generateProvinceInfoForProvinceGcy(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.generateResultMapwithKey("city", result, "获取市信息成功", true)),
                        "公采云-查询市信息接口");
                return ResultMap.generateResultMapwithKey("city", result, "获取市信息成功", true);
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                        "公采云-查询市信息接口");
                return ResultMap.gcyFaileResultMap(e.getMessage());
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileTokenResultMap()),
                    "公采云-查询市信息接口");
            return ResultMap.gcyFaileTokenResultMap();
        }
    }

    /**
     * 公采云获取三级地址
     * @param data
     * @return
     */
    @Override
    public Map getCounty(String data) {
        Map appinfoMap = JsonUtils.str2obj(data, Map.class);//寄送字符串转成map
        String token = String.valueOf(appinfoMap.get("token"));
        String id = String.valueOf(appinfoMap.get("id"));//需要查询的区 所属的市
        //根据token获取appkey
        Store store = new Store().selectOne(new LambdaQueryWrapper<Store>().eq(Store::getAccessToken, token));
        // 判断token是否过期
        boolean isExpired = true;
        String appKey = store.getAppKey();
        try {
            isExpired = storeService.checkAccessToken(appKey, token);
        } catch (ServiceException e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询区信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        } catch (Exception e) {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                    "公采云-查询区信息接口");
            return ResultMap.gcyFaileResultMap(e.getMessage());
        }
        // 如果没有过期
        if (isExpired) {
            try {
                // 区的level=2
                List<Area> areaList = areaMapper.selectAreaCityByProvinceIdAndlevel(2, id);
                // 生成返回字段 city 所需格式
                List<Map> result = this.generateProvinceInfoForProvinceGcy(areaList);
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.gcySuccessResultMapwithKeyandDesc("result",result,"")),
                        "公采云-查询区信息接口");
                return ResultMap.gcySuccessResultMapwithKeyandDesc("result",result,"");
            } catch (ServiceException e) {
                // 日志
                addApiLog(appKey, data,
                        JsonUtils.obj2string(ResultMap.gcyFaileResultMap(e.getMessage())),
                        "公采云-查询区信息接口");
                return ResultMap.gcyFaileResultMap(e.getMessage());
            }
        } else {
            // 日志
            addApiLog(appKey, data,
                    JsonUtils.obj2string(ResultMap.gcyFaileTokenResultMap()),
                    "新点-查询区信息接口");
            return ResultMap.gcyFaileTokenResultMap();
        }
    }

    /**
     * 通用：生成---返回字段 Province 所需要的值
     *
     * @param areaList
     * @return
     */
    private List<Map> generateProvinceInfoForProvince(List<Area> areaList) {
        List<Map> resultlist = new ArrayList<>();
        for (Area area : areaList) {
            Map map = new HashMap();
            map.put("code", area.getId().toString());
            map.put("name", area.getAreaName());
            resultlist.add(map);
        }
        return resultlist;
    }

    /**
     * 公采云通用：生成---返回字段 Province 所需要的值
     *
     * @param areaList
     * @return
     */
    private List<Map> generateProvinceInfoForProvinceGcy(List<Area> areaList) {
        List<Map> resultlist = new ArrayList<>();
        for (Area area : areaList) {
            Map map = new HashMap();
            map.put(area.getAreaName(), area.getId().toString());
            resultlist.add(map);
        }
        return resultlist;
    }

    /**
     * 日志记录
     *
     * @param caller      调用者
     * @param inputvalue  输入参数
     * @param outputvalue 输出参数
     * @param remark      备注
     */
    private void addApiLog(String caller, String inputvalue, String outputvalue, String remark) {
        // 记录调用日志
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Apilog apilog = new Apilog(new Date(), false, "", request.getRequestURL().toString(), caller, inputvalue, outputvalue, remark);
        apilogService.save(apilog);
    }
}
